﻿using System.Collections;
using UnityEngine;

namespace MassiveBattle
{
	public class BattleResultUI : MonoBehaviour
	{
		private Report report;

		[SerializeField]
		private GameObject sequence0;
		[SerializeField]
		private GameObject sequence1;

		[SerializeField]
		private UILabel attackPointTotalLabel;
		[SerializeField]
		private UILabel damagePointTotalLabel;

		[SerializeField]
		private GameObject[] attackPointSlider;
		[SerializeField]
		private GameObject[] damagePointSlider;
		private int sliderActiveCount = 0;

		[SerializeField]
		private float pointSliderTime = 2;

		public void Init(Report report, System.Action onEndEvent)
		{
			Clear();

			this.report = report;

			StartCoroutine(Show(onEndEvent));
		}

		private IEnumerator Show(System.Action onEndEvent)
		{
			sequence0.SetActive(true);
			sequence0.animation.Play();

			yield return new WaitForSeconds(sequence0.animation.clip.length);

			sequence0.SetActive(false);
			sequence1.SetActive(true);
			sequence1.animation.Play();

			yield return new WaitForSeconds(sequence1.animation.clip.length);

			ShowReport();

			yield return new WaitForSeconds(pointSliderTime + 2f);

			Destroy(gameObject);

			if (onEndEvent != null)
				onEndEvent();
		}

		private void Clear()
		{
			sequence0.SetActive(false);
			sequence1.SetActive(false);

			attackPointTotalLabel.text = 0.ToString();
			damagePointTotalLabel.text = 0.ToString();

			for (int i = 1; i <= 5; i++)
			{
				attackPointSlider[i - 1].GetComponent<UIToggle>().value = false;
				attackPointSlider[i - 1].GetComponent<UISlider>().value = 0;

				damagePointSlider[i - 1].GetComponent<UIToggle>().value = false;
				damagePointSlider[i - 1].GetComponent<UISlider>().value = 0;
			}
			sliderActiveCount = 0;
		}

		private void ShowReport()
		{
			int attackPointTotal = 0, attackPointMax = 0;
			int damagePointTotal = 0, damagePointMax = 0;

			for (int i = 1; i <= 5; i++)
			{
				int attackPoint = report.GetAttackPoint(i);
				int damagePoint = report.GetDamagePoint(i);

				attackPointSlider[i - 1].GetComponent<UIToggle>().value = attackPoint != 0;
				damagePointSlider[i - 1].GetComponent<UIToggle>().value = damagePoint != 0;

				attackPointTotal += attackPoint;
				damagePointTotal += damagePoint;

				attackPointMax = attackPoint > attackPointMax ? attackPoint : attackPointMax;
				damagePointMax = damagePoint > damagePointMax ? damagePoint : damagePointMax;
			}

			SetLabelValue(attackPointTotalLabel, attackPointTotal);
			SetLabelValue(damagePointTotalLabel, damagePointTotal);

			for (int i = 1; i <= 5; i++)
			{
				int attackPoint = report.GetAttackPoint(i);
				int damagePoint = report.GetDamagePoint(i);

				SetSliderValue(attackPointSlider[i - 1].GetComponent<UISlider>(), attackPoint, attackPointMax);
				SetSliderValue(damagePointSlider[i - 1].GetComponent<UISlider>(), damagePoint, damagePointMax);
			}
		}

		private void SetLabelValue(UILabel label, int value)
		{
			StartCoroutine(SetLabelValueCoroutine(label, value, pointSliderTime));
		}

		private IEnumerator SetLabelValueCoroutine(UILabel label, int value, float time)
		{
			for (float timeCur = 0; ; )
			{
				label.text = Mathf.CeilToInt(Mathf.Lerp(0, value, timeCur / time)).ToString("#,0");

				if (timeCur >= time)
					break;

				yield return null;

				timeCur += Time.deltaTime;
			}
		}

		private void SetSliderValue(UISlider slider, int value, float valueMax)
		{
			StartCoroutine(SetSliderValueCoroutine(slider, slider.transform.Find("on/value").GetComponent<UILabel>(), value, valueMax, pointSliderTime));
		}

		private IEnumerator SetSliderValueCoroutine(UISlider slider, UILabel label, int value, float valueMax, float time)
		{
			if (sliderActiveCount == 0)
				audio.Play();

			sliderActiveCount++;

			time *= value / valueMax;

			for (float timeCur = 0; ; timeCur += Time.deltaTime)
			{
				int valueCur = Mathf.RoundToInt(Mathf.Lerp(0, value, timeCur / time));

				slider.value = valueCur / valueMax;

				Vector3 position = label.transform.localPosition;
				position.x = slider.foregroundWidget.drawingDimensions.z;

				label.text = valueCur.ToString("#,0");
				label.transform.localPosition = position;

				if (timeCur > time)
					break;

				yield return null;
			}

			sliderActiveCount--;

			if (sliderActiveCount == 0)
				audio.Stop();
		}
	}
}
